
export const socketWebUtil = {
  replaceAt: (dom, appendValue, isAppendLastTag = true, lastOffset) => {
    const innerText = dom?.value || {};
    if (!innerText) return;
    // 额外增加首尾空格
    if (isAppendLastTag) {
      // 末尾添加
      dom.value = `${innerText.slice(0, -1)} @${appendValue} `
    } else {
      // 中间添加
      dom.value = `${innerText.slice(0, lastOffset - 1)} @${appendValue} ${innerText.slice(lastOffset)}`
    }
  },
  notice: msg => {
    // 判断用户是否同意
    if (window.Notification && window.Notification.permission === 'granted') {
      new Notification(msg)
    } else if (window.Notification && Notification.permission !== "denied") {
      // 如果用户没有选择是否显示通知
      Notification.requestPermission(status => {
        if (Notification.permission !== status) Notification.permission = status
        // 用户同意
        if (status === 'granted') new Notification(msg)
      })
    }
  }
}

class Socket {
  constructor(url) {
      this.wsUrl = url;
      this.connectData = {
          lockReconnect: false,
          timeout: null,
      }
      this.heartData = {
          heartTimeout: null,
          heartServerTimeout: null,
          fixHeartTimer: null
      }
      this.createWebsocket()
  }

  createWebsocket() {
      try {
          this.ws = new WebSocket(this.wsUrl);
          this.init();
      }   catch(err) {
          this.reconnect(`try catch Error: \n ${err}`)
      }
  }

  init() {
      const {ws} = this;
      const self = this;

      ws.onerror = err => {
          self.reconnect(`onerror Error: \n ${err}`);
      };

      ws.onclose = () => {
          self.reconnect();
      };

      ws.onopen = () => {
          this.heartStart()
      }
  }

  // 接收服务端返回信息
  handleMessage(callback) {
      const self = this;
      this.ws.onmessage = e => {
        console.log('onmessage>>>', e)
        if (typeof callback === 'function') {
          socketWebUtil.notice('您收到通知了')
          callback(e.data);
        }
        self.heartReset();
      };
  }

  // 发送信息
  handleSendMessage(data) {
    const {ws} = this;
    if (ws.readyState === 1) ws.send(JSON.stringify(data));
    else {
      this.createWebsocket()
    }
  }

  // 重连
  reconnect(error) {
      if (error && process.env.NODE_ENV === 'development') console.warn(`websocket ${error}`);
      const {connectData} = this;
      const {lockReconnect, timeout} = connectData;
      if (lockReconnect) return; // 如果当前正在重连，直接返回
      connectData.lockReconnect = true;
      if (timeout) clearTimeout(timeout); // 关闭定时器
      connectData.timeout = setTimeout(() => { // 5秒后执行
          this.createWebsocket() // 重连
          connectData.lockReconnect = false;
      }, 5000)
  }

  // 心跳
  heartStart(timeout = 10000) {
      const {heartTimeout, heartServerTimeout} = this.heartData;
      const self = this;
      if (heartTimeout) clearTimeout(heartTimeout);
      if (heartServerTimeout) clearTimeout(heartServerTimeout);
      this.heartData.heartTimeout = setTimeout(() => {
          self.ws.send(JSON.stringify({type: 'heart', data: 'HeartBeat'})) // 发送心跳，后台接收
          self.heartData.heartServerTimeout = setTimeout(() => {
              self.ws.close() // 关闭socket，重新触发连接
          }, timeout)
      }, timeout)
  }

  // 重置心跳
  heartReset() {
    const {heartTimeout, heartServerTimeout} = this.heartData;
    clearTimeout(heartTimeout);
    clearTimeout(heartServerTimeout);
    this.heartStart()
  }

  // 每格20s定时轮询心跳
  sendFixHeart() {
    clearInterval(this.heartData.fixHeartTimer);
    this.heartData.fixHeartTimer = setInterval(() => {
      this.ws.send(JSON.stringify({type: 'heart', data: 'HeartBeat'})) // 发送心跳，后台接收
    }, 20000)
  }
}

export default Socket